package com.ec50n9.server.module.doc

import com.ec50n9.server.common.SpringUtils
import com.ec50n9.server.common.render
import com.ec50n9.server.module.common.*
import com.ec50n9.server.module.ebook.Ebook
import com.ec50n9.server.module.ebook.EbookDetailRendered
import com.ec50n9.server.module.ebook.EbookService
import org.hibernate.annotations.GenericGenerator
import org.springframework.beans.BeanUtils
import javax.persistence.*
import javax.validation.constraints.NotBlank

@Entity
class Doc(
    var name: String,
    @OneToOne
    var content: DocContent,
    @ManyToOne
    var ebook: Ebook,
    var sort: Int,
    @ManyToOne
    var parent: Doc? = null,
    var viewCount: Int = 0,
    var voteCount: Int = 0,

    @Id
    @GenericGenerator(name = "nanoid", strategy = "com.ec50n9.server.common.NanoIdGenerator")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "nanoid")
    var id: String? = null
) : Render<Doc>()

@Entity
class DocContent(
    var content: String,

    @Id
    @GenericGenerator(name = "nanoid", strategy = "com.ec50n9.server.common.NanoIdGenerator")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "nanoid")
    var id: String? = null
) : Render<DocContent>()

/**
 * 详情渲染
 */
data class DocDetailRendered(
    var id: String? = null,
    var name: String? = null,
    var content: String? = null,
    var parent: Doc? = null,
    var ebook: EbookDetailRendered? = null,
    var sort: Int? = null,
    var viewCount: Int? = null,
    var voteCount: Int? = null
) : Rendered<Doc> {
    override fun renderFrom(from: Doc) {
        BeanUtils.copyProperties(from, this)
        ebook = from.ebook.renderTo(EbookDetailRendered::class.java)
        content = from.content.content
    }
}

/**
 * 列表渲染
 */
data class DocListRendered(
    var id: String? = null,
    var name: String? = null,
    var ebookName: String? = null,
    var sort: Int? = null,
    var viewCount: Int? = null,
    var voteCount: Int? = null
) : Rendered<Doc> {
    override fun renderFrom(from: Doc) {
        BeanUtils.copyProperties(from, this)
        ebookName = from.ebook.name
    }
}

/**
 * 创建表单
 */
data class DocCreateForm(
    @field:NotBlank(message = "文档名称不能为空")
    var name: String? = null,

    @field:NotBlank(message = "文档内容不能为空")
    var content: String? = null,

    @field:NotBlank(message = "所属电子书不能为空")
    var ebookId: String? = null,
    var sort: Int? = 0
) : CreateForm<Doc> {
    override fun renderTo(): Doc {
        val ebookService = SpringUtils.getBean(EbookService::class.java)
        val docContentService = SpringUtils.getBean(DocContentService::class.java)

        val doc = Doc(
            "",
            docContentService.newOne(DocContent(content!!)),
            ebookService.findOne(ebookId!!),
            0
        )
        render(doc)

        return doc
    }
}

/**
 * 更新表单
 */
data class DocUpdateForm(
    var name: String? = null,
    var content: String? = null,
    var parentId: String? = null,
    var ebookId: String? = null,
    var sort: Int? = null,
    var viewCount: Int? = null,
    var voteCount: Int? = null
) : UpdateForm<Doc> {
    override fun renderTo(doc: Doc) {
        val ebookService = SpringUtils.getBean(EbookService::class.java)
        val docService = SpringUtils.getBean(DocService::class.java)

        render(doc, true)
        parentId?.let { doc.parent = docService.findOne(it) }
        ebookId?.let { doc.ebook = ebookService.findOne(it) }
        content?.let { doc.content.content = it }
    }
}

